CSS - Elementos flutuantes

O browser, por default, sempre utiliza o posicionamento de elementos Static.

Sendo assim os objetos são 'renderizados' na página de cima para baixo, da esquerda para direita e o elemento ( seu box ) pode ser deslocado apenas pelos parâmetros internos dos seus elementos como margin, padding.

Funciona muito bem na maioria das vezes (por isso é o default) e em páginas mais simples mas às vezes não é o suficiente para um design mais elaborado.

Utilizamos elementos flutuantes (float) quando precisamos colocar um elemento na página mas não queremos o alinhamento ou a posição que o web browser normalmente definiria para o elemento.
Podemos através do display float pedir para que a imagem seja alinhada à direita da linha corrente no browser ou à esquerda mas não tem no centro, central ou middle.
Contudo é uma faca de dois gumes, faz o reposicionamento do elemento mas algumas consideraçoes precisam ser levadas em conta para a correta exibição e um cuidado especial deve ser dado ao redimensionamento da janela do browser.

O browser tem o fluxo normal dele que é o style="position:static;" e ele encaixa tudo seguindo este 'fluxo normal'. Contudo ao incluirmos o parâmetro style="float:left" ou style="float:right", por exemplo, o browser posiciona o elemento à direita ou à esquerda da linha desconsiderando o 'fluxo normal' e, digamos que, ele cria um 'fluxo alternativo'. Tudo a partir do primeiro float será posicionado segundo esse 'fluxo alternativo'. Contudo, se quisermos terminar o estilo float temos que utilizar o estilo style="clear: both;" para voltarmos ao position static antigo do browser.


Revisando HTML:


Elementos block : Sempre ocupam a linha inteira, do começo ao fim, mesmo que haja espaço para renderizar outros elementos e se já houver outro elemento na linha a sua esquerda ele irá para a linha posterior.

Exemplo: 2 parágrafos <p> definidos um logo após o outro.

Como foi definido:
Texto Antes do primeiro paragrafo<p>Paragrafo1</p>Texto no meio dos parafos<p>Paragrafo2</p>Texto Depois do segundo paragrafo

Como o browser exibe:
Texto Antes do primeiro paragrafo

Paragrafo1

Texto no meio dos parafos

Paragrafo2

Texto Depois do segundo paragrafo

Note que havia espaço sobrando para exibir Paragrafo2 na mesma linha do Paragrafo1 mas isso não foi feito porque a tag p é renderizada com o estilo block e ocupa uma linha inteira.

A vantagem dos elementos block é que podemos definir dimensões (height e width),margin, padding, ou seja, podemos trabalhar com o design do elemento.
A desvantagem é que só podemos exibir um elemento bloco numa linha do browser de maneira exclusiva, ou seja, se existir algo na linha o elemento bloco será exibido na linha seguinte e se houver espaço para o próximo elemento a ser renderizado, mesmo assim, este será renderizado na linha a seguir.


Elementos inline : Ocupam apenas o espaço que precisam para exibir os seus elementos e se houver espaço na mesma linha para renderizar outro este outro elemento será exibido na mesma linha.

Exemplo: tags <span> seguidas
Como foi definido:
Texto Antes do primeiro span<span>span1</span>Texto do span1 e span2<span>span2</span>Texto depois do span2

Como o browser exibe:
Texto Antes do primeiro spanspan1Texto do span1 e span2span2Texto depois do span2

Note que havia espaço sobrando para exibir Span2 na mesma linha do Span1 e isso foi feito porque a tag span é renderizada com o estilo inline que só ocupa o espaço que precisa para ser exibido.

A vantagem dos elementos inline é que eles ocupam somente o espaço que precisam, dinâmicamente alocado pelo browser. Portanto se a fonte de letras é grande o espaço necessário será aberto para renderizar o elemento corretamente.
A desvantagem dos elementos inline é que não serve para design porque ele não responde aos parâmetros como suas dimensões (height e width),margin, padding, ou seja, o browser é o dono dele e nãopodemos trabalhar com o design do elemento.



Estilo Flutuante

Chamamos de estilo flutuante (float) porque podemos colocar o elemento aonde desejarmos (alinhando ele à esquerda, direita ou centro ) contudo o browser não estará mais encarregado do 'encaixe' dos blocos como no static, de cima para baixo, da esquerda para direita e com isto um elemento pode simplesmente ser 'sobrescrito' por outro.
Tome muito cuidado ao usar estilos flutuantes especialmente em tamanhos de telas diferentes do planejado por você. Sempre teste o estilo flutuante redimensionando a janela do browser para ver se fica razoável.

O browser em seu 'fluxo normal' de renderização dos elementos que é do topo esquerdo do browser para o rodapé direito do mesmo.
Dizemos que o browser tem um segundo fluxo de renderização para os elementos flutuantes - o 'fluxo flutuante'.
Através da CSS podemos pedir para que o elemento seja colocado no 'fluxo flutuante' e posicionado a direita, centro ou esquerda.
Note que o 'fluxo normal' não interage com o 'fluxo flutuante', portanto podemos ter colisão de elementos.

Dizemos que há um 'fluxo normal' de renderização de elementos do browser e outro fluxo chamado 'fluxo flutuante' onde todos os flutuantes serão posicionados.
Note que os estilos utilizados são os mesmos do display:inline e style:block

Importante:
1) Caso um elemento esteja sendo renderizado num estilo inline/block e no elemento seguinte não seja definido o estilo este será renderizado com o estilo do elemento anterior / corrente. O mesmo vale para o estilo flutuante.
Portanto, ao chavear o fluxo para normal ou float este fica valendo até nova definição.
Note que todos os elementos HTML tem estilo inline-block defindos pelo default do browser.
Veja os boxes Conteudo10 a Conteudo12 em relação ao texto que o segue.

2) Caso ao tentar renderizar o elemento inline e ele não caiba totalmente na linha corrente este será renderizado na linha logo a seguir abaixo da atual.

Estilos utilizados nesta página:
    <style type="text/css">
        .styConteudo1 {
            background: blue;
            border: 1px solid red;
            width: 150px;
            height: 150px;
            color:white;
        }

        .styConteudo2 {
            background: green;
            border: 1px solid red;
            width: 150px;
            height: 150px;
            color: white;
        }

        .styConteudo3 {
            background: green;
            border: 1px solid red;
            width: 150px;
            height: 150px;
            float: right;
            color: white;
        }

        .styConteudo4 {
            background: green;
            border: 1px solid red;
            width: 150px;
            height: 150px;
            float: left; /* right e none */
            color: white;
        }

        .styConteudo5 {
            background: pink;
            border: 1px solid red;
            width: 200px;
            height: 200px;
        }

        .styConteudo6 {
            background: green;
            border: 1px solid red;
            width: 150px;
            height: 250px;
            float: left; /* right e none */
        }

        .styClearEsquerda {
            clear: left;
        }

        .styClearDireita {
            clear: right;
        }

        .styClearBoth {
            clear: both;
        }

        .styBorda1pxVM {
            border: 1px solid red;
        }

        .styDisplayInline {
            display: inline;
        }

        .styDisplayInlineBlock {
            display: inline-block;
        }
    </style>

Exibindo elementos tipo Block (div) com o 'fluxo normal'

Definição :
        <div class="styConteudo1">Conteudo1</div>
        <div class="styConteudo1">Conteudo2</div>
        <div class="styConteudo1">Conteudo3</div>

Como o browser exibe:
Conteudo1
Conteudo2
Conteudo3

Misturando elementos block(div) e o float:right

Como foi definido:
        <div class="styConteudo3">Conteudo4</div><--Esta aqui tem float:right-->
        <div class="styConteudo2">Conteudo5</div>
        <div class="styConteudo2">Conteudo6</div>
        <div>no box Conteudo4 aplicamos o '<b>float right</b>'. Note que elementos Conteudo5 e Conteudo6 foram alinhados à esquerda como se Conteudo4, à direita, não existisse porque o certo seria que fossem renderizados logo abaixo(elemento tipo block).
</div>

Como o browser exibe:
Conteudo4
Conteudo5
Conteudo6
no box Conteudo4 aplicamos o 'float right'. Note que elementos Conteudo5 e Conteudo6 foram alinhados à esquerda como se Conteudo4, à direita, não existisse porque o certo seria que fossem renderizados logo abaixo(elemento tipo block).

Sobrepondo elementos com float

Como foi definido:
        <div class="styConteudo4">Conteudo7</div><--Esta aqui tem float:left-->
        <div class="styConteudo5">Conteudo8</div>
        <div class="styConteudo5">Conteudo9</div>
        <div>no box Conteudo7 aplicamos o '<b>float left</b>'. Ai quando o browser foi exibir o box Conteudo8 ele ignorou o box Conteudo7 e o Conteudo7 ficou sobreposto ao Conteudo8.</div>
        <div>note que o float deu um '<b>top most</b>' no elemento float, o box Conteudo7, porque apesar do 8 ser exibido depois o 7 ficou em cima.</div>


Como o browser exibe :
Conteudo7
Conteudo8
Conteudo9
no box Conteudo7 aplicamos o 'float left'. Ai quando o browser foi exibir o box Conteudo8 ele ignorou o box Conteudo7 e o Conteudo7 ficou sobreposto ao Conteudo8.
Contudo note que o float deu um 'top most' no elemento float, o box Conteudo7, porque apesar do 8 ser exibido depois o 7 ficou em cima.
Importante : Utilizar clear-right, clear-left ou clear-both para que o browser avalie o espaço ocupado pelos elementos float e evite a superposição de elementos.

Exibindo múltipos elementos flutuantes à esquerda

Como foi definido:
        <div class="styConteudo4">Conteudo10</div><--Esta aqui tem float:left-->
        <div class="styConteudo4">Conteudo11</div><--Esta aqui tem float:left-->
        <div class="styConteudo4">Conteudo12</div><--Esta aqui tem float:left-->
        <div>
            Nos boxes Conteudo10,11 e 12 aplicamos o '<b>float left</b>'. <br /><br />
            Note que o Conteudo10 ficou a esquerda e na hora que o browser foi exibir o box Conteudo11 ele encontrou no 'fluxo float' o Conteudo10 e exibiu o 11 o mais a esquerda que pode, ou seja, a direita do box Conteudo10.<br /><br />
            Importante: Note que o texto foi renderizado no '<b>fluxo float</b>' pois se fosse no '<b>fluxo normal</b>' ele deveria ter sido colocado abaixo dos boxes exibidos já que o elemento div é elemento inline.
        </div>

Como o browser exibe:
Conteudo10
Conteudo11
Conteudo12
Nos boxes Conteudo10,11 e 12 aplicamos o 'float left'.

Note que o Conteudo10 ficou a esquerda e na hora que o browser foi exibir o box Conteudo11 ele encontrou no 'fluxo float' o Conteudo10 e exibiu o 11 o mais a esquerda que pode, ou seja, a direita do box Conteudo10.

Importante: Note que o texto foi renderizado no 'fluxo float' pois se fosse no 'fluxo normal' ele deveria ter sido colocado abaixo dos boxes exibidos já que o elemento div é elemento inline.

Para a linha acima :'Nos boxes Conteudo10,11 e 12 aplicamos...' fosse exibida abaixo dos boxes tive que colocar na tag que tem o texto o etilo para limpar o float. Isto faz com que o texto seja renderizado logo abaixo do último elemento float senão seria exibido à direita dos boxes.
Código : ... style="clear: both;"


Exibindo múltipos elementos flutuantes à direita

Como foi definido:
        <div class="styConteudo3">Conteudo13</div><--Esta aqui tem float:right-->
        <div class="styConteudo3">Conteudo14</div><--Esta aqui tem float:right-->
        <div class="styConteudo3">Conteudo15</div><--Esta aqui tem float:right-->
        <div>
            Nos boxes Conteudo13,14 e 15 aplicamos o '<b>float right</b>'. <br /><br />
            Note que o Conteudo13 ficou a direita e na hora que o browser foi exibir o box Conteudo14 também a direita ele encontrou no 'fluxo float' o Conteudo13 e exibiu o 14 o mais a direita que pode, ou seja, a esquerda do box Conteudo13.<br /><br />
            Importante: Note que o texto foi renderizado no '<b>fluxo float</b>' pois se fosse no '<b>fluxo normal</b>' ele deveria ter sido colocado abaixo dos boxes exibidos já que o elemento div é elemento inline.
        </div>

Como o browser exibe:
Conteudo13
Conteudo14
Conteudo15
Nos boxes Conteudo 13,14 e 15 aplicamos o 'float right'.

Note que o Conteudo13 ficou a direita e na hora que o browser foi exibir o box Conteudo14 também a direita ele encontrou no 'fluxo float' o Conteudo13 e exibiu o 14 o mais a direita que pode, ou seja, a esquerda do box Conteudo13.

Importante: Note que o texto foi renderizado no 'fluxo float' pois se fosse no 'fluxo normal' ele deveria ter sido colocado abaixo dos boxes exibidos já que o elemento div é elemento inline.

Novamente utilizei o estilo style="clear: both;" para que o texto 'Nos boxes Conteudo...' ficassem abaixo dos boxes e não à esquerda dos mesmos.


Exibindo múltipos elementos flutuantes à direita misturados com à esquerda

Como foi definido:
        <div class="styConteudo2">Conteudo16</div>
        <div class="styConteudo3">Conteudo17</div><--Esta aqui tem float:right-->
        <div class="styConteudo3">Conteudo18</div><--Esta aqui tem float:right-->
        <div class="styConteudo3">Conteudo19</div><--Esta aqui tem float:right-->
        <div>
            No box Conteudo16 não aplicamos nenhum estilo float. <br />
            Nos boxes Conteudo17,18 e 19 aplicamos o '<b>float right</b>'. <br />
            Quando o box Conteudo16 foi exibido normalmente o próximo elemento seria exibido na linha abaixo pela regra do fluxo normal. <br />
            Note que o Conteudo17 ficou a direita e na hora que o browser foi exibir o box Conteudo18 também a direita ele encontrou no 'fluxo float' o Conteudo17 e exibiu o 18 o mais a direita que pode, ou seja, a esquerda do box Conteudo17.<br />
            Importante: Note que o texto foi renderizado no '<b>fluxo float</b>' pois se fosse no '<b>fluxo normal</b>' ele deveria ter sido colocado abaixo dos boxes exibidos já que o elemento div é elemento inline.
        </div>

Como o browser exibe:
Conteudo16
Conteudo17
Conteudo18
Conteudo19
No box Conteudo16 não aplicamos nenhum estilo float.
Nos boxes Conteudo17,18 e 19 aplicamos o 'float right'.
Quando o box Conteudo16 foi exibido normalmente o próximo elemento seria exibido na linha abaixo pela regra do fluxo normal.
Note que o Conteudo17 ficou a direita e na hora que o browser foi exibir o box Conteudo18 também a direita ele encontrou no 'fluxo float' o Conteudo17 e exibiu o 18 o mais a direita que pode, ou seja, a esquerda do box Conteudo17.
Importante1: Note que o texto foi renderizado no 'fluxo float' pois se fosse no 'fluxo normal' ele deveria ter sido colocado abaixo dos boxes exibidos já que o elemento div é elemento inline.
Importante 2: tem um estilo tyle="clear: both; neste texto para que seja renderizado abaixo dos boxes.

Elementos com tamanhos diferentes e como são afetados no redimensionamento do browser

Como foi definido:
<div class="styConteudo6">Conteudo20</div><--Esta aqui tem float:left-->
<div class="styConteudo4">Conteudo21</div><--Esta aqui tem float:left-->
<div class="styConteudo4">Conteudo22</div><--Esta aqui tem float:left-->
<div>
Nos boxes Conteudo20,21 e 22 aplicamos o '<b>float left</b>'. <br /><br />
Note que o Conteudo20 é muito maior que o 21 e 22.<br /><br />
Reduzindo a largura do browser quando o box Conteudo22 for deslocado para baixo ele encontra o grande Conteudo20 e o renderiza a direita deste ao invés de em baixo.
        </div>

Como o browser exibe:
Conteudo20
Conteudo21
Conteudo22
Nos boxes Conteudo20,21 e 22 aplicamos o 'float left'.

Note que o Conteudo20 é muito maior que o 21 e 22.

Reduzindo a largura do browser quando o box Conteudo22 for deslocado para baixo ele encontra o grande Conteudo20 e o renderiza a direita deste ao invés de em baixo.
Importante: tem um estilo tyle="clear: both; neste texto para que seja renderizado abaixo dos boxes.

Utilizando display float e display Clear

Como foi definido:
     <div class="styConteudo4">Conteudo23</div><--Esta aqui tem float:left-->
     <div class="styConteudo4">Conteudo24</div><--Esta aqui tem float:left-->
     <div class="styConteudo4">Conteudo25</div><--Esta aqui tem float:left-->
     <div>Texto1 sem classe.</div>
     <div class="styClearEsquerda"><--Esta aqui tem clear:right-->
      Texto2 com classe Clear.<br />
      Nos boxes Conteudo23,24 e 25 aplicamos o '<b>float left</b>'. <br /><br />
      Na caixa de texto2 colocamos um estilo para limpar o float left dos parágrafos anteriores.<br />
      Com isto o texto foi exibido corretamente após as caixas.<br />
      Note que o clear no style left fez o texto2 ser posicionado abaixo dos elementos como se fosse dado um inline dos objetos anteriores.<br />
     </div>

Como o browser exibe:
Conteudo23
Conteudo24
Conteudo25
Texto1 sem classe.
Texto2 com classe Clear.
Nos boxes Conteudo23,24 e 25 aplicamos o 'float left'.

Na caixa de texto2 colocamos um estilo para limpar o float left dos parágrafos anteriores.
Com isto o texto foi exibido corretamente após as caixas.
Note que o clear no style left fez o texto2 ser posicionado abaixo dos elementos como se fosse dado um inline dos objetos anteriores.

Tags Divs e estilo float

Caso uma tag-container comum, sem float, contenha outras tags-filhas com float, o espaço ocupada pelas tags filhas será desconsiderado pela tag-container. Veja só o exemplo abaixo:

Como foi definido:
        <div style="border:5px solid red;background-color:pink;">
            <div class="styConteudo3">Conteudo26</div><--Esta aqui tem float:right-->
            <div class="styConteudo3">Conteudo27</div><--Esta aqui tem float:right-->
            <div class="styConteudo3">Conteudo28</div><--Esta aqui tem float:right-->
            <div>
                Texto sem classe.<br />
            </div>
        </div>


Como o browser exibe:
Conteudo26
Conteudo27
Conteudo28
Texto sem classe.

A div com borda vermelha contém as divs com os boxes verdes mas as divs dos boxes verdes estão com float-right.
Note que quando uma div normal contém divs float dentro ela desconsidera o volume dessas divs float internas a ela.
Importante: tem um estilo tyle="clear: both; neste texto para que seja renderizado abaixo dos boxes.




Tags Divs e estilo float

Utilizando o clear:right no exemplo acima o erro é corrigido.

Como foi definido:
        <div style="border:5px solid red;background-color:pink;">
            <div class="styConteudo3">Conteudo29</div>
            <div class="styConteudo3">Conteudo30</div>
            <div class="styConteudo3">Conteudo31</div>
            <div class="styClearDireita">Conteudo32</div><--Esta aqui tem clear:right-->
            <div>
                Texto sem classe.<br />
            </div>
        </div>


Como o browser exibe:
Conteudo29
Conteudo30
Conteudo31
Conteudo32
Texto sem classe.
É o mesmo do exemplo anterior.
No entanto a div Conteudo32 contem o clear-right o que faz com que o background da div pai seja redimensionado para a altura dos elementos filhos.